home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-11-26 | 64.7 KB | 2,511 lines |
- Newsgroups: comp.sources.misc
- organization: Eindhoven University of Technology, The Netherlands
- keywords: pc-mail-nfs
- subject: v09i006: pc-mail over nfs
- from: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
- Reply-To: wietse@wzv.win.tue.nl (Wietse Z. Venema)
-
- Posting-number: Volume 9, Issue 6
- Submitted-by: wietse@wzv.win.tue.nl (Wietse Z. Venema)
- Archive-name: pc-mail-nfs
-
- This is an extension to the pc-mail package (uucp mail for pc's) that
- appeared in comp.sources.misc, april 1988. It is intended for an
- environment where pc-mail users mount their personal mail directories
- from a file server. The programs in the present package run on the file
- server. They directly access the per-user pc-mail directories and thus
- replace the UUCP file transfer functions of the pc-mail software. The
- programs were tested with SunOS 4.0.3 and Microport System-V/AT 2.3.
- This software is in the public domain.
-
- Wietse Venema (wswietse@lso.win.tue.nl)
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: README pc-mail.c pc-maild.c Makefile sysexits.h syslog.h
- # syslog.c util.c util.h mtime.c mtime.h dosunix.c dosunix.h
- # percentm.h percentm.c pc-mail.8 pc-maild.8
- # Wrapped by wietse@wzv on Sun Nov 19 14:01:07 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(6589 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X@(#) README 1.6 11/19/89 14:00:51
- X
- XThis is an extension to the pc-mail package (uucp mail for pc's) that
- Xappeared in comp.sources.misc, april 1988. It is intended for an
- Xenvironment where pc-mail users mount their personal mail directories
- Xfrom a file server. The programs in the present package run on the file
- Xserver. They directly access the per-user pc-mail directories and thus
- Xreplace the UUCP file transfer functions of the pc-mail software. The
- Xprograms were tested with SunOS 4.0.3 and Microport System-V/AT 2.3.
- XThis software is in the public domain.
- X
- XPlease report any problems etc. to the author (Wietse Venema) via one
- Xof the following e-mail addresses:
- X
- X wswietse@lso.win.tue.nl
- X wswietse@heitue5.bitnet
- X
- XThe remainder of this document describes the operation of the software,
- Xhow to install the software, how to add new users, and how to migrate
- Xusers from pc-mail over UUCP to pc-mail over PC-NFS.
- X
- XOperation
- X=========
- X
- XThe UUCP file transfer functions of the pc-mail "cico.exe" program are
- Xtaken over by the following two programs that run on the file server:
- X
- Xpc-mail: deliver mail to a user's mail directory (the receiving
- X function of the "cico.exe" program). This program is
- X intended to be called by sendmail.
- X
- Xpc-maild: scan user mail directories for unsent mail, and pipe it
- X through the UNIX rmail command (the sending function of
- X the "cico.exe" program).
- X
- XInstallation on the server
- X==========================
- X
- XBuild the pc-mail and pc-maild programs. In the Makefile, you can
- Xdefine the location of the executable programs and the pc-mail spool
- Xarea, and how often the daemon program will scan user directories for
- Xunsent mail. You will probably have to do `make depend' before you
- Xcan compile the programs.
- X
- XExecute the following command to create a pc-mail spool area, and
- Xinstall the pc-mail and pc-maild programs. You must be root.
- X
- X % make install
- X
- XThe output from the "make" command will depend on how you specified the
- Xpath names in the Makefile:
- X
- X mkdir /var/spool/pc-mail
- X chmod 755 /var/spool/pc-mail
- X cp pc-mail pc-maild /usr/local/lib
- X chown root /usr/local/lib/pc-mail
- X chmod u+s /usr/local/lib/pc-mail
- X
- XExecute the following command to install the manual pages, if you want
- Xto.
- X
- X % make installman
- X
- XAgain, output from make will depend on what you specified in the
- XMakefile:
- X
- X cp pc-mail.8 pc-maild.8 /usr/local/man/man8
- X
- XAdd a line with the command
- X
- X /usr/local/lib/pc-maild
- X
- Xto the file /etc/rc.local (the exact name of the rc script depends on
- Xyour version of unix, and the exact path name of the pc-maild program
- Xdepends on where you installed it).
- X
- XFor now, you will have to start the pc-maild program by hand (unless
- Xyou wish to reboot the machine).
- X
- XAdd to the sendmail.cf file a line that looks like:
- X
- X Mpc, P=/usr/local/lib/pc-mail, F=lsDFMn, S=xxx, R=yyy, A=pc-mail $u
- X
- XWhere xxx and yyy may be the same rewriting rules as used for the local
- Xmailer (usually defined with the "Mlocal" line).
- X
- XIn sendmail.cf, at the end of ruleset S0, just before the local mailer
- Xwill be invoked (something like "R$* $#local $:$1"), add a line with
- X
- X R $=X $#pc $:$1
- X
- XUse a different letter if X is already in use. A later section
- Xdescribes how to convince sendmail that X is a list of login names of
- Xpc-mail users.
- X
- XAdding users (server side)
- X==========================
- X
- XAdd the user to the password data base. In the spool area on the
- Xserver, create a subdirectory for the pc-mail user. The directory must
- Xbe owned by that user; for reasons of privacy, mode 0700 is recommended.
- XIn the following example, replace username by the actual login name of
- Xthe user.
- X
- X % mkdir /var/spool/pc-mail/username
- X % chown username /var/spool/pc-mail/username
- X % chmod 700 /var/spool/pc-mail/username
- X
- XAdding users (pc side)
- X======================
- X
- XOn the pc, adjust the AUTOEXEC.BAT, NETWORK.BAT or DRIVES.BAT files so
- Xthat they contain the following commands (replacing server by the name
- Xof the NFS server host, and replacing username by the login name of the
- Xactual user):
- X
- X net name username *
- X net use m: \\server\var\spool\pc-mail\username
- X set MAILDIR=m:\
- X
- XThe trailing \ is needed on the last command, or the mail program will
- Xcomplain that it "cannot access some essential data files".
- X
- XIf the user had a UUCP-based pc-mail link, you can now remove the -p
- Xoption from any CMAIL commands that may appear in batch files.
- X
- XReboot the pc.
- X
- XIf the user had a UUCP-based pc-mail link, copy the contents of the
- Xuser's LOCAL mail directory to the REMOTE mail directory on the file
- Xserver. From now on the local mail directory will no longer be needed.
- X
- XTest if the mail program works by creating a small mail message. Since
- Xthe message will automatically be picked up by the pc-maild program the
- Xfiles may disappear before you had a chance to type a DIR command!
- X
- XAdding users (server side again)
- X================================
- X
- XAdd the user to the list of NFS pc-mail users. There are two ways to
- Xaccomplish the same result. The list of users can be hardcoded in the
- Xsendmail.cf file, e.g.:
- X
- X CXjohn marsha
- X
- XMultiple usernames on a line, and multiple CX lines are allowed. A
- Xbetter way is to have sendmail read the list from an external file,
- Xby putting the following line into the sendmail.cf file:
- X
- X FX/etc/pc-mail-users %s
- X
- XThe /etc/pc-mail-users file should contain only a single login name per
- Xline.
- X
- XKill the sendmail daemon and restart it.
- X
- XIf the user had a UUCP-based pc-mail connection, you can now get rid of
- Xaliases that were needed for UUCP support.
- X
- XNote that the sendmail ON THE NFS SERVER will not read the user's
- X.forward file. The file will still be useful, however, if the user's
- Xhome directory is exported to OTHER hosts running sendmail. In that
- Xcase you will want to create a .forward file in the user's home
- Xdirectory containing
- X
- X username@fully-qualified-hostname
- X
- XAdding users (pc side again)
- X============================
- X
- XThis step can be skipped if the user had no UUCP-based pc-mail connection.
- X
- XIf the user used to have a UUCP connection, pick up any mail that still
- Xresides in the UUCP spool area on the file server (the mail will now be
- Xstored in the user's private remote mail directory through the miracles
- Xof NFS).
- X
- XAt this point the cico.exe program has become obsolete. You may consider
- Xto replace it by a small C program that does nothing.
- X
- XAdding users (server side again)
- X================================
- X
- XThis step can be skipped if the user had no UUCP-based pc-mail connection.
- X
- XThe user's uucp login can be removed from the password file.
- END_OF_FILE
- if test 6589 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'pc-mail.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'pc-mail.c'\"
- else
- echo shar: Extracting \"'pc-mail.c'\" \(10884 characters\)
- sed "s/^X//" >'pc-mail.c' <<'END_OF_FILE'
- X/*++
- X/* NAME
- X/* pc-mail 8
- X/* SUMMARY
- X/* deliver mail to nfs-based pc-mail users
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* nfs
- X/* SYNOPSIS
- X/* pc-mail user
- X/* DESCRIPTION
- X/* This program is to be run on the nfs server that exports mail
- X/* directories to MS-DOS pc-mail users. The program replaces the
- X/* UNIX -> MS-DOS file transfer function of the MS-DOS \fIcico\fR
- X/* program.
- X/*
- X/* Normally, the pc-mail delivery program is invoked by sendmail(8).
- X/* Its purpose is to deliver new mail in the mail directory of the
- X/* specified \fIuser\fR (default /var/spool/pc-mail/\fIuser\fR).
- X/* Any error conditions detected by the pc-mail delivery program
- X/* are reported back in a sendmail-compatible manner.
- X/*
- X/* This program must be run with root privileges. It will assume
- X/* the (uid, gid) of the specified user before delivering mail.
- X/*
- X/* The program attempts to create any missing directories, and to
- X/* correct ownerships or protections where needed.
- X/* FILES
- X/* /usr/spool/pc-mail/\fIuser\fR/nNNNNN, mail message.
- X/* /usr/spool/pc-mail/\fIuser\fR/hNNNNN, sender of message.
- X/* (NNNNN is the pc-mail "message id").
- X/* SEE ALSO
- X/* pc-maild(1)
- X/* DIAGNOSTICS
- X/* All conceivable error conditions cause the program to terminate
- X/* with a non-zero exit status, after printing an error message on
- X/* the standard error stream, and appending an entry to the system log.
- X/* See <sysexits.h> for details.
- X/* BUGS
- X/* There is no way to notify a pc-mail user of the arrival of new mail.
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Oct 22 18:00:53 MED 1989
- X/* LAST MODIFICATION
- X/* 11/19/89 13:46:04
- X/* VERSION/RELEASE
- X/* 1.2
- X/*--*/
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) pc-mail.c 1.2 11/19/89 13:46:04";
- X
- X#endif
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <pwd.h>
- X#include <varargs.h>
- X
- X#ifdef SYSLOG
- X#include <syslog.h>
- X#else
- X#include "syslog.h"
- X#endif
- X
- X#ifdef SYSV
- X#include <ndir.h>
- X#else
- X#include <sys/dir.h>
- X#endif
- X
- X#ifdef SYSEXITS
- X#include <sysexits.h>
- X#else
- X#include "sysexits.h"
- X#endif
- X
- X#include "dosunix.h"
- X#include "percentm.h"
- X
- X/* Stuff related to failed system calls */
- X
- Xextern int errno;
- X
- X/* External functions */
- X
- Xextern struct passwd *getpwnam();
- Xextern long time();
- Xextern char *mktemp();
- Xextern void exit();
- Xextern unsigned sleep();
- X
- X/* Local declarations */
- X
- X#ifndef MAILDIR
- X#define MAILDIR "/usr/spool/pc-mail" /* pc-mail directory tree */
- X#endif
- X
- X#define LOCK "pc-mail.lck" /* the lock file */
- X#define STALE 1800 /* max age of lock file */
- X#define MAXTRY 60 /* max retry count for lock creation */
- X#define MSGFIL_FMT "n%05d" /* message file name format */
- X#define SNDFIL_FMT "h%05d" /* sender file name format */
- X
- Xchar template[] = "pc.XXXXXX"; /* template lock file */
- X
- X/* local functions */
- X
- Xvoid sender();
- Xvoid message();
- Xvoid error();
- X
- Xchar *progname;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X struct passwd *pwd;
- X static char userdir[BUFSIZ];
- X int seqno;
- X
- X progname = argv[0];
- X
- X /* Garbage in, garbage out */
- X
- X if (argc != 2)
- X error(EX_USAGE, "usage: %s user", *argv);
- X
- X#ifndef DEBUG
- X if (geteuid() != 0)
- X error(EX_USAGE, "must run with root privileges");
- X
- X /* need this for SYSVR2 or mkdir(1) fails */
- X#ifdef SYSV
- X if (setuid(0) != 0)
- X error(EX_OSERR, "cannot setuid(0)");
- X#endif
- X#endif
- X
- X if ((pwd = getpwnam(argv[1])) == 0)
- X error(EX_NOUSER, "unknown user: %s", argv[1]);
- X
- X /* Setup a somewhat safe environment */
- X
- X if (putenv("PATH=/bin:/usr/bin:/usr/ucb")
- X || putenv("IFS= \t\n"))
- X error(EX_TEMPFAIL, "putenv() failed");
- X
- X /* Check the necessary directories exist */
- X
- X (void) sprintf(userdir, "%s/%s", MAILDIR, argv[1]);
- X checkdir(userdir, pwd->pw_uid, pwd->pw_gid, 0700);
- X
- X /* Now with that out of the way, try to deliver the message */
- X
- X if (setgid(pwd->pw_gid))
- X error(EX_USAGE, "setgid(%s) failed: %m", argv[1]);
- X if (setuid(pwd->pw_uid))
- X error(EX_USAGE, "setuid(%s) failed: %m", argv[1]);
- X
- X /* make sure the user mail directory is accessible */
- X
- X if (chdir(userdir))
- X error(EX_TEMPFAIL, "can't access mail directory %s", userdir);
- X
- X /* deliver mail */
- X
- X seqno = newseqno(userdir); /* Allocate sequence number */
- X message(pwd, seqno); /* Create message file */
- X sender(seqno); /* Create metafile (sender) */
- X exit(EX_OK); /* Done. */
- X /* NOTREACHED */
- X}
- X
- X/* message - write message file */
- X
- Xvoid message(pwd, seqno)
- Xstruct passwd *pwd;
- Xint seqno;
- X{
- X static char buf[BUFSIZ];
- X register FILE *fp;
- X
- X /* Create the message file */
- X
- X (void) sprintf(buf, MSGFIL_FMT, seqno);
- X if ((fp = fopen(buf, "w")) == 0)
- X error(EX_CANTCREAT, "create error for file %s/%s: %m",
- X pwd->pw_name, buf);
- X if (unix2dos(stdin, fp)) {
- X (void) unlink(buf);
- X error(EX_CANTCREAT, "write error for file %s/%s: %m",
- X pwd->pw_name, buf);
- X }
- X (void) fclose(fp);
- X (void) chmod(buf, 0400); /* Avoid tampering */
- X}
- X
- X/* sender - extract sender from message */
- X
- Xvoid sender(seqno)
- Xint seqno;
- X{
- X register FILE *ifp;
- X register FILE *ofp;
- X static char fname[BUFSIZ]; /* file names */
- X static char line[BUFSIZ]; /* read buffer */
- X static char from[BUFSIZ] = "unknown"; /* sender */
- X
- X /*
- X * Try to open the message file; if that fails, let the pc software scan
- X * for the sender at a later time.
- X *
- X * We recognize the following From line formats:
- X *
- X * From name
- X *
- X * >From name
- X *
- X * From: address (full name)
- X *
- X * From: full name <address>
- X *
- X * From: full name
- X */
- X
- X (void) sprintf(fname, MSGFIL_FMT, seqno);
- X if ((ifp = fopen(fname, "r")) == 0)
- X return;
- X
- X /* Extract sender from message */
- X
- X while (dosgets(line, sizeof(line), ifp) && *line) {
- X if (sscanf(line, "From: %*s ( %[^)] )", from) == 1)
- X break;
- X if (sscanf(line, "From: %[^<]", from) == 1)
- X break;
- X sscanf(line, "%*[>] From %s", from) || sscanf(line, "From %s", from);
- X }
- X (void) fclose(ifp);
- X
- X /*
- X * Try to create the meta file; if that fails, let the pc software try
- X * again at a later time.
- X */
- X
- X (void) sprintf(fname, SNDFIL_FMT, seqno);
- X if (ofp = fopen(fname, "w")) {
- X (void) fprintf(ofp, "%s\r\n", from);
- X if (fflush(ofp) || ferror(ofp) || feof(ofp) || fclose(ofp)) {
- X (void) unlink(fname);
- X } else {
- X (void) chmod(fname, 0400); /* avoid tampering */
- X }
- X }
- X}
- X
- X/* newseqno - allocate new message sequence number */
- X
- Xint newseqno(userdir)
- Xchar *userdir;
- X{
- X register DIR *dd;
- X register struct direct *p;
- X struct stat st;
- X register int seqno = 0;
- X int tmp = 0;
- X int i;
- X char junk;
- X
- X /*
- X * When the pc adds a file to the "mail data base", the file name is
- X * composed of a single letter and a unique sequence number. The pc
- X * chooses a new sequence number by adding one to the highest existing
- X * sequence number.
- X *
- X * Now that the pc mounts its mail directory from the nfs server we must
- X * avoid possible concurrency conflicts when both pc and file server try
- X * to update the "mail data base".
- X *
- X * Since the pc does not know about concurrent access from the nfs server,
- X * the server has to add 2 to the highest existing message sequence
- X * number, in order to avoid conflicts. Fortunately, only one pc at a
- X * time will be accessing a mail directory of a particular user.
- X *
- X * Further concurrency conflicts are be avoided on the server side by using
- X * lock files.
- X *
- X * If we cannot create a lock file right now, we back off and let sendmail
- X * try again later.
- X */
- X
- X /* Get rid of stale lock files */
- X
- X if (stat(LOCK, &st) == 0 && st.st_mtime < time((long *) 0) - STALE)
- X (void) unlink(LOCK);
- X
- X /* Wait until we can create the lock file */
- X
- X if (creat(mktemp(template), 0400) < 0)
- X error(EX_TEMPFAIL, "cannot set lock in directory %s: check ownership",
- X userdir);
- X for (i = 0; link(template, LOCK) && i < MAXTRY; i++)
- X (void) sleep(1);
- X (void) unlink(template);
- X if (i >= MAXTRY)
- X error(EX_TEMPFAIL, "locked: %s", userdir);
- X
- X /* Scan the user mail directory for the highest existing message number */
- X
- X if ((dd = opendir(userdir)) == 0) {
- X (void) unlink(LOCK);
- X error(EX_TEMPFAIL, "opendir(\"%s\") failed: %m", userdir);
- X }
- X while (p = readdir(dd)) {
- X if (sscanf(p->d_name + 1, "%d%c", &tmp, &junk) == 1 && tmp > seqno)
- X seqno = tmp;
- X }
- X
- X /* clean up and terminate */
- X
- X closedir(dd);
- X (void) unlink(LOCK);
- X return (seqno + 2);
- X}
- X
- X/* checkdir - check/update presence/ownership/protection of directory */
- X
- Xcheckdir(path, uid, gid, mode)
- Xchar *path;
- Xint uid;
- Xint gid;
- Xint mode;
- X{
- X struct stat st;
- X
- X /*
- X * If a user mail directory does not exist, try to create it. Otherwise,
- X * make sure it has sane permissions
- X */
- X
- X if (stat(path, &st) == -1) { /* no directory */
- X if (mkdir(path, mode)) /* try to create it */
- X error(EX_TEMPFAIL, "cannot create directory %s: %m", path);
- X if (chown(path, uid, gid)) /* set owner, group */
- X error(EX_TEMPFAIL, "cannot chown directory %s: %m", path);
- X } else { /* directory exists */
- X if ((st.st_mode & S_IFMT) != S_IFDIR) /* must be directory! */
- X error(EX_TEMPFAIL, "%s should be a directory", path);
- X if ((st.st_uid != uid || st.st_gid != gid) /* check owner/group */
- X &&chown(path, uid, gid)) /* correct owner, group */
- X error(EX_TEMPFAIL, "cannot chown directory %s: %m", path);
- X if ((st.st_mode & 0777) != mode /* check permissions */
- X && chmod(path, mode)) /* correct permissions */
- X error(EX_TEMPFAIL, "cannot chmod %o directory %s: %m", mode, path);
- X }
- X}
- X
- X/* error - print diagnostic and terminate */
- X
- X/* VARARGS */
- X
- Xvoid error(va_alist) va_dcl
- X{
- X va_list ap;
- X register int exstat;
- X register char *fmt;
- X char buf[BUFSIZ];
- X int err = errno;
- X
- X /* Format the error message */
- X
- X va_start(ap);
- X exstat = va_arg(ap, int); /* exit status */
- X fmt = va_arg(ap, char *); /* format string */
- X (void) vsprintf(buf, percentm(fmt, err), ap);
- X va_end(ap);
- X
- X /* Write message to standard error stream */
- X
- X (void) fprintf(stderr, "%s: %s\n", progname, buf);
- X
- X /* Append the same message to system log */
- X
- X (void) openlog("pc-mail", LOG_PID, LOG_MAIL);
- X (void) syslog(LOG_WARNING, "%s", buf);
- X (void) closelog();
- X
- X /* Notify sendmail of the nature of the problem */
- X
- X exit(exstat);
- X}
- X
- X#ifdef SYSV
- X
- X/* mkdir - create directory */
- X
- Xint mkdir(dir, mode)
- Xchar *dir;
- Xint mode;
- X{
- X char cmd[BUFSIZ];
- X
- X sprintf(cmd, "mkdir %s 2>&1 >/dev/null 2>&1 && chmod %o %s",
- X dir, mode, dir);
- X return (system(cmd)); /* does not set errno */
- X}
- X
- X#endif
- END_OF_FILE
- if test 10884 -ne `wc -c <'pc-mail.c'`; then
- echo shar: \"'pc-mail.c'\" unpacked with wrong size!
- fi
- # end of 'pc-mail.c'
- fi
- if test -f 'pc-maild.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'pc-maild.c'\"
- else
- echo shar: Extracting \"'pc-maild.c'\" \(13746 characters\)
- sed "s/^X//" >'pc-maild.c' <<'END_OF_FILE'
- X/*++
- X/* NAME
- X/* pc-maild 8
- X/* SUMMARY
- X/* deliver unsent mail
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* nfs
- X/* SYNOPSIS
- X/* pc-maild [delay]
- X/* DESCRIPTION
- X/* This program should be run on the nfs file server that exports
- X/* mail directories to MS-DOS pc-mail users. It replaces the
- X/* (MS-DOS -> UNIX) transmission function of the MS-DOS \fIcico\fR
- X/* program.
- X/*
- X/* The per-user mail directories (default: /var/spool/pc-mail/\fIuser\fR)
- X/* are scanned for outgoing mail every \fIdelay\fR seconds (default: 300).
- X/* When outgoing mail is found, it is sent through the UNIX rmail program
- X/* (uucp mail interface) and the corresponding files are removed from the
- X/* user\'s mail directory.
- X/*
- X/* The program should run with root privileges. It will assume
- X/* the (uid, gid) of the sending user before accessing mail files.
- X/* COMMANDS
- X/* rmail(1), uucp mail interface program
- X/* FILES
- X/* /usr/spool/pc-mail/\fIuser\fR/dNNNNN, mail message
- X/* /usr/spool/pc-mail/\fIuser\fR/xNNNNN, recipients
- X/* (NNNNN is the pc-mail "message id").
- X/* SEE ALSO
- X/* pc-mail(1)
- X/* DIAGNOSTICS
- X/* Errors found during initialization cause the program to
- X/* terminate with a diagnostic on the standard error stream.
- X/* All other errors are considered transient, i.e. if something
- X/* fails, it is tried again at a later time. Where possible,
- X/* diagnostics are logged through the syslog facility.
- X/* BUGS
- X/* Scanning mail directories is an inefficient way to detect
- X/* unsent mail.
- X/* AUTHOR(S)
- X/* W.Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Oct 22 22:12:15 MED 1989
- X/* LAST MODIFICATION
- X/* 10/31/89 15:44:54
- X/* VERSION/RELEASE
- X/* 1.3
- X/*--*/
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) pc-maild.c 1.3 10/31/89 15:44:54";
- X
- X#endif
- X
- X /*
- X * General return-value conventions:
- X *
- X * int func(): 0 means OK
- X *
- X * stuff *func(): 0 means error
- X *
- X */
- X
- X#include <stdio.h>
- X#include <pwd.h>
- X#include <time.h>
- X#include <signal.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X#ifdef SYSLOG
- X#include <syslog.h>
- X#else
- X#include "syslog.h"
- X#endif
- X
- X#ifdef SYSV
- X#include <sys/utsname.h>
- X#include <ndir.h>
- X#else
- X#include <sys/types.h>
- X#include <sys/dir.h>
- X#include <sgtty.h>
- X#endif
- X
- X#include "dosunix.h"
- X#include "util.h"
- X#include "mtime.h"
- X
- X/* Library functions */
- X
- Xextern char *strtok();
- Xextern char *strncpy();
- Xextern struct passwd *getpwnam();
- Xextern unsigned sleep();
- Xextern void exit();
- Xextern void _exit();
- Xextern struct tm *localtime();
- Xextern char *asctime();
- Xextern long time();
- X
- X/* Local defines, declarations */
- X
- X#ifndef DELAY
- X#define DELAY 300 /* default: scan every 5 minutes */
- X#endif
- X
- X#ifndef MAILDIR
- X#define MAILDIR "/usr/spool/pc-mail" /* default pc-mail directory tree */
- X#endif
- X
- X
- Xvoid catchsig();
- Xvoid finduser();
- Xchar *getrcpt();
- Xchar *fullname();
- X
- Xint delay = DELAY; /* the default delay */
- Xchar *progname; /* my process name */
- X
- X
- Xint main(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X progname = *argv;
- X
- X /* Sanity checks */
- X
- X#ifndef DEBUG
- X
- X if (geteuid() != 0) {
- X fprintf(stderr, "%s: must be run as root\n", progname);
- X exit(1);
- X }
- X#endif
- X
- X /* Check for command-line delay argument */
- X
- X if (argc > 1 && (delay = atoi(argv[1])) < 1)
- X delay = DELAY;
- X
- X /* Become a daemon process */
- X
- X#ifndef DEBUG
- X disconnect();
- X#endif
- X
- X /* Set up signal handling */
- X
- X catchsig();
- X
- X /* Enable syslogging */
- X
- X (void) openlog(progname, LOG_PID, LOG_MAIL);
- X syslog(LOG_WARNING, "daemon restarted");
- X
- X /* Setup a decent environment */
- X
- X if (putenv("PATH=/bin:/usr/bin:/usr/ucb") || putenv("IFS= \t\n")) {
- X syslog(LOG_WARNING, "initialization failed (insufficient resources)");
- X exit(1);
- X }
- X /* Enter the main loop */
- X
- X finduser();
- X /* NOTREACHED */
- X}
- X
- X/* finduser - repeatedly iterate over all pc-mail user directories */
- X
- Xvoid finduser()
- X{
- X register DIR *maildp;
- X register struct direct *dp;
- X register struct passwd *uinfo;
- X MTIME *dirtime;
- X char userdir[BUFSIZ];
- X struct stat st;
- X
- X /*
- X * Ignore names that start with a period.
- X *
- X * Ignore names that do not correspond to a directory.
- X *
- X * Ignore directories that did not change since the last time they were
- X * known to hold no unsent mail.
- X *
- X * Ignore directories that do not have a name equal to the login name of a
- X * user.
- X */
- X
- X for (;;) {
- X if ((e_chdir(MAILDIR) == 0) && (maildp = e_opendir(MAILDIR))) {
- X while (dp = readdir(maildp)) {
- X if ((dp->d_name[0] != '.')
- X && (stat(dp->d_name, &st) == 0)
- X && ((st.st_mode & S_IFMT) == S_IFDIR)
- X && (st.st_mtime > (dirtime = mtime(dp->d_name))->time)
- X && ((uinfo = getpwnam(dp->d_name)) != 0)) {
- X (void) sprintf(userdir, "%s/%s", MAILDIR, dp->d_name);
- X if (findmail(uinfo, userdir) == 0)
- X dirtime->time = st.st_mtime; /* say it was empty */
- X }
- X }
- X closedir(maildp); /* done with this user */
- X (void) chdir("/"); /* be friendly */
- X }
- X (void) sleep(delay); /* try again later */
- X }
- X}
- X/* findmail - enter a user\'s mail directory and scan for unsent mail */
- X
- Xint findmail(uinfo, userdir)
- Xstruct passwd *uinfo;
- Xchar *userdir;
- X{
- X register DIR *dd;
- X register struct direct *p;
- X int seqno;
- X static char xfile[BUFSIZ]; /* file with recipients */
- X static char dfile[BUFSIZ]; /* file with mail message */
- X int found = 0; /* no mail found yet */
- X
- X /*
- X * Use the fact that 'x' files (recipient addresses) are created later
- X * than 'd' files (message body) when a pc user generates a message.
- X * Extract the pc-mail message id from the file name and try to pipe the
- X * message through the UNIX rmail command. All knowledge about pc-mail
- X * file names resides in this function. Return zero if no unsent mail was
- X * found.
- X */
- X
- X if ((e_chdir(userdir) == 0) && (dd = e_opendir(userdir))) {
- X while (p = readdir(dd)) {
- X if (*p->d_name == 'x' && sscanf(p->d_name + 1, "%d", &seqno) == 1) {
- X (void) sprintf(xfile, "x%05d", seqno); /* recipients */
- X if (strcmp(p->d_name, xfile) == 0) { /* ignore junk */
- X (void) sprintf(dfile, "d%05d", seqno);
- X pickup(uinfo, xfile, dfile);
- X found = 1; /* found unsent mail */
- X }
- X }
- X }
- X closedir(dd);
- X (void) chdir(MAILDIR);
- X }
- X return (found);
- X}
- X
- X/* pickup - pick up one message from a user\'s mail directory */
- X
- Xpickup(uinfo, xfile, dfile)
- Xstruct passwd *uinfo;
- Xchar *xfile;
- Xchar *dfile;
- X
- X{
- X
- X /*
- X * Actual delivery must be done with the (uid, gid) of the sender, or the
- X * From: lines will not be correct. Therefore, we do delivery in a child
- X * process. This also avoid all kinds of nasty security problems. All
- X * errors are considered non-fatal.
- X */
- X
- X#ifdef DEBUG
- X sendasuser(uinfo, xfile, dfile); /* don't fork */
- X#else
- X switch (e_fork()) {
- X case -1: /* failure */
- X break;
- X case 0: /* child */
- X sendasuser(uinfo, xfile, dfile);
- X _exit(0);
- X /* NOTREACHED */
- X default: /* parent */
- X (void) wait((int *) 0);
- X break;
- X }
- X#endif
- X}
- X
- X/* sendasuser - send mail through rmail(1), having (uid, gid) of sender */
- X
- Xsendasuser(uinfo, xfile, dfile)
- Xstruct passwd *uinfo;
- Xchar *xfile;
- Xchar *dfile;
- X{
- X char *dest; /* recipient address(es) */
- X
- X /*
- X * User-specific mail files must be opened AFTER we have assumed the
- X * (uid, gid) of the pc-mail user; this in order to avoid nasty security
- X * holes.
- X */
- X
- X if ((setugid(uinfo) == 0) /* assume proper (uid, gid) */
- X &&(dest = getrcpt(uinfo, xfile)) /* extract recipients */
- X &&(rmail(uinfo, dfile, dest) == 0)) { /* pipe message through rmail */
- X (void) u_unlink(uinfo, xfile); /* recipients file */
- X (void) u_unlink(uinfo, dfile); /* message body file */
- X }
- X}
- X
- X/* setugid - assume (uid, gid) of user */
- X
- Xint setugid(uinfo)
- Xstruct passwd *uinfo;
- X{
- X if (setgid(uinfo->pw_gid)) {
- X syslog(LOG_WARNING, "setgid(%s) failed: %m", uinfo->pw_name);
- X return (1);
- X }
- X if (setuid(uinfo->pw_uid)) {
- X syslog(LOG_WARNING, "setuid(%s) failed: %m", uinfo->pw_name);
- X return (1);
- X } else {
- X return (0);
- X }
- X}
- X
- X/* getrcpt - extract recipient from user mail file */
- X
- Xchar *getrcpt(uinfo, xfile)
- Xstruct passwd *uinfo;
- Xchar *xfile;
- X{
- X FILE *xfp; /* recipient file pointer */
- X static char dest[2 * BUFSIZ]; /* recipient names */
- X register char *ret;
- X
- X if ((xfp = u_fopen(uinfo, xfile, "r")) == 0) {
- X return (0);
- X } else {
- X pc_wait(fileno(xfp)); /* let pc finish writing */
- X ret = dosgets(dest, sizeof(dest), xfp);
- X (void) fclose(xfp);
- X if (ret == 0)
- X syslog(LOG_WARNING, "no recipients specified in %s/%s",
- X uinfo->pw_name, xfile);
- X return (ret);
- X }
- X}
- X
- X/* rmail - pipe a pc mail message through the UNIX rmail program */
- X
- Xint rmail(uinfo, dfile, dest)
- Xstruct passwd *uinfo; /* originator */
- Xchar *dfile; /* message file */
- Xchar *dest; /* recipients */
- X{
- X static char cmd[BUFSIZ * 2]; /* command + arguments */
- X FILE *dfp; /* source stream */
- X FILE *pfp; /* output stream */
- X int ret; /* return value, 0 if OK */
- X long secs; /* absolute UNIX time */
- X static char hostname[BUFSIZ]; /* our host name */
- X
- X /*
- X * The UNIX rmail command needs a UUCP-style From_ line.
- X *
- X * The To: and From: lines can be added for esthetical porposes.
- X *
- X * Report communication failures with the rmail command. Error returns from
- X * rmail are ignored; they should be handled in sendmail.
- X */
- X
- X if (dfp = u_fopen(uinfo, dfile, "r")) { /* open message file */
- X sprintf(cmd, "rmail %s", dest);
- X if ((pfp = popen(cmd, "w")) == 0) { /* invoke rmail... */
- X syslog(LOG_WARNING, "cannot invoke %.20s...: %m", rmail);
- X ret = 1;
- X } else {
- X secs = time((long *) 0);
- X (void) gethostname(hostname, sizeof(hostname));
- X fprintf(pfp, "From %s %.24s remote from %s\n", uinfo->pw_name,
- X asctime(localtime(&secs)),
- X hostname); /* add UUCP From_ line */
- X#ifdef RFC822
- X rfc822hdr(uinfo, dest, pfp); /* do RFC822 stuff */
- X#endif
- X if (ret = dos2unix(dfp, pfp)) /* append message body */
- X syslog(LOG_WARNING, "write to rmail failed: %m");
- X (void) pclose(pfp);
- X }
- X (void) fclose(dfp);
- X }
- X return (ret);
- X}
- X
- X/* rfc822hdr - generate subset of RFC822 header lines */
- X
- Xrfc822hdr(uinfo, dest, pfp)
- Xregister struct passwd *uinfo;
- Xchar *dest;
- Xregister FILE *pfp;
- X{
- X char *sep = " ,\t\r\n";
- X char *name;
- X
- X /*
- X * There are a few problems with this function. First of all, it destroys
- X * the dest argument. In the second place, putting each recipient on a
- X * separate To: header line is ugly.
- X */
- X
- X fprintf(pfp, "From: %s (%s)\n", uinfo->pw_name,
- X fullname(uinfo)); /* add From: header line */
- X for (name = strtok(dest, sep); name; name = strtok((char *) 0, sep))
- X fprintf(pfp, "To: %s\n", name); /* add To: header line */
- X}
- X
- X/* fullname - extract full name from gecos field */
- X
- Xchar *fullname(uinfo)
- Xstruct passwd *uinfo;
- X{
- X static char name[BUFSIZ];
- X
- X /* This code assumes BSD-style gecos fields (name,stuff,stuff...) */
- X
- X if (sscanf(uinfo->pw_gecos, "%[^,]", name) == 0)
- X name[0] = '\0';
- X return (name);
- X}
- X
- X/* gotsig - caught a signal; terminate with diagnostic */
- X
- Xvoid gotsig(sig)
- Xint sig;
- X{
- X syslog(LOG_WARNING, "going down on signal %d", sig);
- X closelog();
- X exit(sig);
- X}
- X
- X/* catchsig - catch some signals */
- X
- Xvoid catchsig()
- X{
- X#ifdef DEBUG
- X (void) signal(SIGHUP, gotsig);
- X (void) signal(SIGINT, gotsig);
- X (void) signal(SIGQUIT, gotsig);
- X#else
- X (void) signal(SIGHUP, SIG_IGN);
- X (void) signal(SIGINT, SIG_IGN);
- X (void) signal(SIGQUIT, SIG_IGN);
- X#endif
- X (void) signal(SIGBUS, gotsig);
- X (void) signal(SIGSEGV, gotsig);
- X (void) signal(SIGTERM, gotsig);
- X}
- X
- X/* disconnect - become a daemon process */
- X
- Xdisconnect()
- X{
- X#ifndef SYSV
- X int fd;
- X
- X#endif
- X
- X /* Get rid of the parent process */
- X
- X switch (e_fork()) {
- X case -1: /* failure */
- X exit(1);
- X /* NOTREACHED */
- X default:
- X _exit(0); /* parent */
- X /* NOTREACHED */
- X case 0: /* child */
- X break;
- X }
- X
- X /* Get rid of the controlling terminal */
- X
- X (void) close(0);
- X (void) close(1);
- X (void) close(2);
- X#ifdef SYSV
- X (void) setpgrp();
- X#else
- X if ((fd = open("/dev/tty", 0)) >= 0) {
- X (void) ioctl(fd, TIOCNOTTY, 0);
- X (void) close(fd);
- X }
- X#endif
- X}
- X
- X/* pc_wait - wait till the pc has finished writing a file */
- X
- Xpc_wait(fd)
- Xint fd;
- X{
- X struct stat st;
- X long oldsize = 0;
- X
- X /*
- X * Repeatedly sleep one second until the file size does not change
- X * anymore.
- X *
- X * At first sight, this does not seem to be a very robust algorithm. It is,
- X * however, sufficient. The pc sofware will first create a message file,
- X * then the file with recipient addresses. The pc-maild program, on the
- X * other hand, will read the recipient-address file first. If that file
- X * turns out to be empty, it will try again at a later time. So, the only
- X * time we may produce an incorrect result is under the following
- X * conditions:
- X *
- X * (1) the file with recipient names is longer than the PC/NFS packet size
- X * or the pc\'s stdio buffer size.
- X *
- X * (2) the network connection goes down for > 1 second after part of the
- X * data has arrived in the file with recipient addresses.
- X */
- X
- X while (fstat(fd, &st) == 0 && oldsize != st.st_size) {
- X oldsize = st.st_size;
- X sleep(1);
- X }
- X}
- X
- X#ifdef SYSV
- X
- X/* gethostname - BSD compatibility routine */
- X
- Xgethostname(name, len)
- Xchar *name;
- Xint len;
- X{
- X struct utsname ut;
- X
- X uname(&ut);
- X (void) strncpy(name, ut.nodename, len);
- X return (0);
- X}
- X
- X#endif
- END_OF_FILE
- if test 13746 -ne `wc -c <'pc-maild.c'`; then
- echo shar: \"'pc-maild.c'\" unpacked with wrong size!
- fi
- # end of 'pc-maild.c'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(4401 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X# @(#) Makefile 1.5 11/19/89 13:53:47
- X
- X###############################
- X# Start of configurable options. You will also have to do a `make depend'.
- X
- X# Compiler options.
- X# -DSYSV is needed for system 5 release 2
- X# -DRFC822 if you want the daemon to produce To: and From: header lines
- X# -DSYSEXITS if your system has <sysexits.h>
- X# -DSYSLOG if your system has a BSD 4.3-like syslog facility
- X# -DSYSLOGFILE=\"/usr/spool/mqueue/syslog\" if you don't have BSD4.3-like syslog
- X# You will also have to create that file, with mode 666.
- X#
- X#BSD4.X: DEFS = -DRFC822 -DSYSEXITS -DSYSLOG
- X#SYSVR2: DEFS = -DRFC822 -DSYSV -DSYSLOGFILE=\"/usr/spool/mqueue/syslog\"
- X
- XDEFS = -DRFC822 -DSYSEXITS -DSYSLOG
- X
- X# Location of pc-mail spool area
- X
- XMAILDIR = /var/spool/pc-mail
- X
- X# How often the daeman will scan the pc-mail spool area for unsent mail.
- X# This time interval can also be changed via the command line.
- X
- XDELAY = 30
- X
- X# Some system-5 implementations have a separate library with BSD-compatible
- X# directory access routines.
- X#
- X#LIBS = -lndir
- X
- XLIBS =
- X
- X# Location of the pc-mail en pc-maild binaries
- X
- XEXEDIR = /usr/local/lib
- X
- X# If you want to, where to install the manual pages
- X
- XMANDIR = /usr/local/man/man8
- X
- X# End of configurable options
- X#############################
- X
- XSHELL = /bin/sh
- XCFLAGS = $(DEFS) -DDELAY=$(DELAY) -DMAILDIR=\"$(MAILDIR)\"
- XARCHIVE = sarch
- XSOURCES = README pc-mail.c pc-maild.c Makefile sysexits.h syslog.h \
- X syslog.c util.c util.h mtime.c mtime.h dosunix.c dosunix.h \
- X percentm.h percentm.c
- X
- XPCMOBJ = pc-mail.o syslog.o percentm.o dosunix.o
- XPCMSRC = pc-mail.c syslog.c percentm.c dosunix.c
- X
- XPCMDOBJ = pc-maild.o syslog.o percentm.o dosunix.o util.o mtime.o
- XPCMDSRC = pc-maild.c syslog.c percentm.c dosunix.c util.c mtime.c
- X
- Xall: pc-mail pc-maild
- X
- Xinstall: all
- X -mkdir $(MAILDIR)
- X chmod 755 $(MAILDIR)
- X cp pc-mail pc-maild $(EXEDIR)
- X chown root $(EXEDIR)/pc-mail
- X chmod 4755 $(EXEDIR)/pc-mail
- X
- Xinstallman:
- X cp pc-mail.8 pc-maild.8 $(MANDIR)
- X
- Xpc-mail: $(PCMOBJ)
- X $(CC) $(CFLAGS) -o $@ $(PCMOBJ) $(LIBS)
- X
- Xpc-maild: $(PCMDOBJ)
- X $(CC) $(CFLAGS) -o $@ $(PCMDOBJ) $(LIBS)
- X
- Xlint: lint1 lint2
- X
- Xlint1: $(PCMSRC)
- X lint $(CFLAGS) $(PCMSRC)
- X
- Xlint2: $(PCMDSRC)
- X lint $(CFLAGS) $(PCMDSRC)
- X
- Xshar: $(SOURCES) pc-mail.8 pc-maild.8
- X @shar $(SOURCES) pc-mail.8 pc-maild.8
- X
- Xclean:
- X rm -f *.o core nohup.out
- X
- Xclobber: clean
- X rm -f pc-maild pc-mail *.8
- X
- Xarchive: $(SOURCES)
- X $(ARCHIVE) $?;
- X touch archive
- X
- Xdepend:
- X (sed '1,/^# do not edit/!d' Makefile; \
- X for i in [a-z][a-z]*.c; do \
- X $(CC) -E $(CFLAGS) $$i | sed -n '/^# *1 *"\([^"]*\)".*/{;s//'`echo $$i|sed 's/c$$/o/'`': \1/;p;}'; \
- X done)>$$$$ && mv $$$$ Makefile
- X
- X# do not edit below this line - it was create with `make depend'
- Xdosunix.o: dosunix.c
- Xdosunix.o: /usr/include/stdio.h
- Xdosunix.o: ./dosunix.h
- Xmtime.o: mtime.c
- Xmtime.o: /usr/include/syslog.h
- Xmtime.o: ./mtime.h
- Xpc-mail.o: pc-mail.c
- Xpc-mail.o: /usr/include/stdio.h
- Xpc-mail.o: /usr/include/sys/types.h
- Xpc-mail.o: /usr/include/sys/sysmacros.h
- Xpc-mail.o: /usr/include/sys/stat.h
- Xpc-mail.o: /usr/include/pwd.h
- Xpc-mail.o: /usr/include/varargs.h
- Xpc-mail.o: /usr/include/syslog.h
- Xpc-mail.o: /usr/include/sys/dir.h
- Xpc-mail.o: /usr/include/sysexits.h
- Xpc-mail.o: ./dosunix.h
- Xpc-mail.o: ./percentm.h
- Xpc-maild.o: pc-maild.c
- Xpc-maild.o: /usr/include/stdio.h
- Xpc-maild.o: /usr/include/pwd.h
- Xpc-maild.o: /usr/include/time.h
- Xpc-maild.o: /usr/include/signal.h
- Xpc-maild.o: /usr/include/vm/faultcode.h
- Xpc-maild.o: /usr/include/sys/types.h
- Xpc-maild.o: /usr/include/sys/sysmacros.h
- Xpc-maild.o: /usr/include/sys/stat.h
- Xpc-maild.o: /usr/include/syslog.h
- Xpc-maild.o: /usr/include/sys/types.h
- Xpc-maild.o: /usr/include/sys/dir.h
- Xpc-maild.o: /usr/include/sgtty.h
- Xpc-maild.o: /usr/include/sys/ioctl.h
- Xpc-maild.o: /usr/include/sys/ttychars.h
- Xpc-maild.o: /usr/include/sys/ttydev.h
- Xpc-maild.o: /usr/include/sys/ttold.h
- Xpc-maild.o: /usr/include/sys/ioccom.h
- Xpc-maild.o: /usr/include/sys/ttycom.h
- Xpc-maild.o: /usr/include/sys/filio.h
- Xpc-maild.o: /usr/include/sys/ioccom.h
- Xpc-maild.o: /usr/include/sys/sockio.h
- Xpc-maild.o: /usr/include/sys/ioccom.h
- Xpc-maild.o: ./dosunix.h
- Xpc-maild.o: ./util.h
- Xpc-maild.o: ./mtime.h
- Xpercentm.o: percentm.c
- Xpercentm.o: /usr/include/stdio.h
- Xpercentm.o: ./percentm.h
- Xsyslog.o: syslog.c
- Xutil.o: util.c
- Xutil.o: /usr/include/stdio.h
- Xutil.o: /usr/include/pwd.h
- Xutil.o: /usr/include/sys/types.h
- Xutil.o: /usr/include/sys/sysmacros.h
- Xutil.o: /usr/include/sys/dir.h
- Xutil.o: /usr/include/syslog.h
- Xutil.o: ./util.h
- END_OF_FILE
- if test 4401 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'sysexits.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sysexits.h'\"
- else
- echo shar: Extracting \"'sysexits.h'\" \(972 characters\)
- sed "s/^X//" >'sysexits.h' <<'END_OF_FILE'
- X/*++
- X/* NAME
- X/* sysexits 5
- X/* SUMMARY
- X/* exit status codes for programs called by sendmail
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* nfs
- X/* SYNOPSIS
- X/* #include "sysexits.h"
- X/* DESCRIPTION
- X/* .nf
- X
- X /* sendmail-compatible exit status codes */
- X
- X#define EX_OK 0
- X#define EX_USAGE 64
- X#define EX_DATAERR 65
- X#define EX_NOINPUT 66
- X#define EX_NOUSER 67
- X#define EX_NOHOST 68
- X#define EX_UNAVAILABLE 69
- X#define EX_SOFTWARE 70
- X#define EX_OSERR 71
- X#define EX_OSFILE 72
- X#define EX_CANTCREAT 73
- X#define EX_IOERR 74
- X#define EX_TEMPFAIL 75
- X#define EX_PROTOCOL 76
- X#define EX_NOPERM 77
- X/* AUTHOR(S)
- X/* Wietse Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/*
- X/* These codes were actually defined by Eric Allman, the originator
- X/* of the sendmail program.
- X/* CREATION DATE
- X/* Sun Oct 29 16:03:19 MET 1989
- X/* LAST MODIFICATION
- X/* 10/29/89 22:29:47
- X/* VERSION/RELEASE
- X/* 1.1
- X/*--*/
- X
- END_OF_FILE
- if test 972 -ne `wc -c <'sysexits.h'`; then
- echo shar: \"'sysexits.h'\" unpacked with wrong size!
- fi
- # end of 'sysexits.h'
- fi
- if test -f 'syslog.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'syslog.h'\"
- else
- echo shar: Extracting \"'syslog.h'\" \(698 characters\)
- sed "s/^X//" >'syslog.h' <<'END_OF_FILE'
- X/*++
- X/* NAME
- X/* syslog 5
- X/* SUMMARY
- X/* surrogate BSD4.3 syslog facility
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* nfs
- X/* SYNOPSIS
- X/* include "syslog.h"
- X/* DESCRIPTION
- X/* .nf
- X
- X /* Do nothing if we already have <syslog.h> */
- X
- X#ifndef SYSLOG
- X
- X /* various constants */
- X
- X#define LOG_PID 1
- X#define LOG_MAIL 1
- X#define LOG_WARNING 1
- X
- Xextern openlog();
- Xextern syslog();
- Xextern closelog();
- X
- X#endif
- X/* AUTHOR(S)
- X/* Wietse Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Oct 29 15:12:57 MET 1989
- X/* LAST MODIFICATION
- X/* 10/29/89 22:29:50
- X/* VERSION/RELEASE
- X/* 1.1
- X/*--*/
- X
- END_OF_FILE
- if test 698 -ne `wc -c <'syslog.h'`; then
- echo shar: \"'syslog.h'\" unpacked with wrong size!
- fi
- # end of 'syslog.h'
- fi
- if test -f 'syslog.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'syslog.c'\"
- else
- echo shar: Extracting \"'syslog.c'\" \(2657 characters\)
- sed "s/^X//" >'syslog.c' <<'END_OF_FILE'
- X/*++
- X/* NAME
- X/* syslog 3
- X/* SUMMARY
- X/* surrogate BSD4.3 syslog facility
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* nfs
- X/* SYNOPSIS
- X/* include "syslog.h"
- X/*
- X/* openlog(name, logopt, facility)
- X/* char *name;
- X/* int logopt;
- X/* int facility;
- X/*
- X/* syslog(priority, format, arguments)
- X/* int priority;
- X/* char *format;
- X/*
- X/* closelog()
- X/* DESCRIPTION
- X/* These functions emulate the BSD4.3 syslog(3) facility. Output is
- X/* written to a system logfile (default /usr/spool/mqueue/syslog).
- X/* That file should have mode 666 (i.e. read/write access permitted
- X/* for everyone).
- X/*
- X/* syslog() tries to output the log entry as one big chunk.
- X/* FILES
- X/* /usr/spool/mqueue/syslog, system logfile
- X/* SEE ALSO
- X/* percentm(3), interprets "%m" sequences in syslog format strings.
- X/* BUGS
- X/* The functions use the stdio package. This may cause the program to
- X/* grow unexpectedly.
- X/* AUTHOR(S)
- X/* Wietse Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Oct 29 15:12:57 MET 1989
- X/* LAST MODIFICATION
- X/* 10/29/89 22:58:33
- X/* VERSION/RELEASE
- X/* 1.2
- X/*--*/
- X
- X#ifndef SYSLOG
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) syslog.c 1.2 10/29/89 22:58:33";
- X
- X#endif
- X
- X#include <stdio.h>
- X#include <varargs.h>
- X#include <time.h>
- X#include "percentm.h"
- X
- Xextern struct tm *localtime();
- Xextern char *asctime();
- Xextern long time();
- Xextern int errno;
- X
- X#ifndef SYSLOGFILE
- X#define SYSLOGFILE "/usr/spool/mqueue/syslog"
- X#endif
- X
- Xstatic char *logname;
- X
- X/* openlog - initialize syslog facility; ignores all but the "name" argument */
- X
- X/* ARGSUSED */
- X
- Xopenlog(name, logopt, facility)
- Xchar *name;
- Xint logopt;
- Xint facility;
- X{
- X logname = name; /* ignore rest */
- X}
- X
- X/* syslog - append entry to system log */
- X
- X/* VARARGS */
- X
- Xsyslog(va_alist)
- Xva_dcl
- X{
- X va_list ap;
- X char *fmt;
- X char *percentm();
- X long secs;
- X char *date;
- X FILE *fp;
- X int err = errno;
- X static char buf[BUFSIZ];
- X
- X if (fp = fopen(SYSLOGFILE, "a")) {
- X
- X /* Format the time stamp */
- X
- X secs = time((long *) 0);
- X date = asctime(localtime(&secs));
- X (void) sprintf(buf, "%2.2s-%3.3s-%2.2s %8.8s %s: ",
- X date + 8, date + 4, date + 22, date + 11, logname);
- X
- X /* Format the actual message */
- X
- X va_start(ap);
- X (void) va_arg(ap, int); /* skip priority */
- X fmt = va_arg(ap, char *);
- X (void) vsprintf(buf + strlen(buf), percentm(fmt, err), ap);
- X va_end(ap);
- X
- X /* Try to ouput the log entry as one big chunk */
- X
- X (void) fprintf(fp, "%s\n", buf);
- X (void) fclose(fp);
- X }
- X}
- X
- X/* closelog - a real dummy */
- X
- Xcloselog()
- X{
- X /* no-op */
- X}
- X
- X#endif /* SYSLOG */
- X
- END_OF_FILE
- if test 2657 -ne `wc -c <'syslog.c'`; then
- echo shar: \"'syslog.c'\" unpacked with wrong size!
- fi
- # end of 'syslog.c'
- fi
- if test -f 'util.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util.c'\"
- else
- echo shar: Extracting \"'util.c'\" \(2780 characters\)
- sed "s/^X//" >'util.c' <<'END_OF_FILE'
- X/*++
- X/* NAME
- X/* util 3
- X/* SUMMARY
- X/* wrappers around standard library functions
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* nfs
- X/* SYNOPSIS
- X/* #include <stdio.h>
- X/* #include <pwd.h>
- X/* #include <directory_access_stuff.h>
- X/*
- X/* FILE *u_fopen(uinfo,path,mode)
- X/* struct passwd *uinfo;
- X/* char *path;
- X/* char *mode;
- X/*
- X/* int u_unlink(uinfo, path)
- X/* struct passwd *uinfo;
- X/* char *path;
- X/*
- X/* DIR *e_opendir(path)
- X/* char *path;
- X/*
- X/* int e_chdir(path)
- X/* char *path;
- X/*
- X/* int e_fork()
- X/* DESCRIPTION
- X/* These functions are wrappers around some standard library functions.
- X/* In case of problems, they append an entry to the system log (with
- X/* priority LOG_WARNING). The \fIuinfo\fR argument specifies the owner
- X/* of the mail subdirectory in which the problem occurred.
- X/* SEE ALSO
- X/* syslog(3)
- X/* DIAGNOSTICS
- X/* Diagnostics are logged via the syslog package; error return values
- X/* are identical to those of the underlying library functions.
- X/* AUTHOR(S)
- X/* Wietse Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Oct 29 16:21:02 MET 1989
- X/* LAST MODIFICATION
- X/* 10/29/89 22:29:53
- X/* VERSION/RELEASE
- X/* 1.1
- X/*--*/
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) util.c 1.1 10/29/89 22:29:53";
- X
- X#endif
- X
- X#include <stdio.h>
- X#include <pwd.h>
- X
- X#ifdef SYSV
- X#include <ndir.h>
- X#else
- X#include <sys/types.h>
- X#include <sys/dir.h>
- X#endif
- X
- X#ifdef SYSLOG
- X#include <syslog.h>
- X#else
- X#include "syslog.h"
- X#endif
- X
- X#include "util.h" /* consistency check */
- X
- X/* u_fopen - open file in user directory, log any errors */
- X
- XFILE *u_fopen(uinfo, file, mode)
- Xstruct passwd *uinfo;
- Xchar *file;
- Xchar *mode;
- X{
- X register FILE *fp;
- X
- X if ((fp = fopen(file, mode)) == 0)
- X syslog(LOG_WARNING, "cannot open %s/%s: %m", uinfo->pw_name, file);
- X return (fp);
- X}
- X
- X/* u_unlink - unlink file in user directory, log any errors */
- X
- Xint u_unlink(uinfo, file)
- Xstruct passwd *uinfo;
- Xchar *file;
- X{
- X register int stat;
- X
- X if (stat = unlink(file))
- X syslog(LOG_WARNING, "cannot unlink %s/%s: %m", uinfo->pw_name, file);
- X return (stat);
- X}
- X
- X/* e_opendir - open directory, log any errors */
- X
- XDIR *e_opendir(path)
- Xchar *path;
- X{
- X register DIR *dd;
- X
- X if ((dd = opendir(path)) == 0)
- X syslog(LOG_WARNING, "cannot open directory %s: %m", path);
- X return (dd);
- X}
- X
- X/* e_chdir - change directory, log any errors */
- X
- Xint e_chdir(path)
- Xchar *path;
- X{
- X register int ret;
- X
- X if (ret = chdir(path))
- X syslog(LOG_WARNING, "cannot chdir to directory %s: %m", path);
- X return (ret);
- X}
- X
- X/* e_fork - do a fork(), log any errors */
- X
- Xint e_fork()
- X{
- X register int stat;
- X
- X if ((stat = fork()) == -1)
- X syslog(LOG_WARNING, "fork() failed: %m");
- X return (stat);
- X}
- X
- END_OF_FILE
- if test 2780 -ne `wc -c <'util.c'`; then
- echo shar: \"'util.c'\" unpacked with wrong size!
- fi
- # end of 'util.c'
- fi
- if test -f 'util.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util.h'\"
- else
- echo shar: Extracting \"'util.h'\" \(1060 characters\)
- sed "s/^X//" >'util.h' <<'END_OF_FILE'
- X/*++
- X/* NAME
- X/* util 3
- X/* SUMMARY
- X/* wrappers around standard library functions
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* nfs
- X/* SYNOPSIS
- X/* #include <stdio.h>
- X/* #include <pwd.h>
- X/* #include "util.h"
- X/* DESCRIPTION
- X/* .nf
- X
- X /* Anticipate on ANSI-compatible compilers */
- X
- X#ifdef __STDC__
- XFILE *u_fopen(struct passwd * user, char *file, char *mode);
- Xint u_unlink(char *file);
- XDIR *e_opendir(char *path);
- Xint e_chdir(char *path);
- Xint e_fork(void);
- X
- X#else
- XFILE *u_fopen(); /* open file, log any errors */
- Xint u_unlink(); /* unlink file, log any errors */
- XDIR *e_opendir(); /* open directory, log any errors */
- Xint e_chdir(); /* change directory, log any errors */
- Xint e_fork(); /* fork, log any errors */
- X
- X#endif
- X/* AUTHOR(S)
- X/* Wietse Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Oct 29 16:21:02 MET 1989
- X/* LAST MODIFICATION
- X/* 10/29/89 22:29:55
- X/* VERSION/RELEASE
- X/* 1.1
- X/*--*/
- X
- END_OF_FILE
- if test 1060 -ne `wc -c <'util.h'`; then
- echo shar: \"'util.h'\" unpacked with wrong size!
- fi
- # end of 'util.h'
- fi
- if test -f 'mtime.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mtime.c'\"
- else
- echo shar: Extracting \"'mtime.c'\" \(2331 characters\)
- sed "s/^X//" >'mtime.c' <<'END_OF_FILE'
- X/*++
- X/* NAME
- X/* mtime 3
- X/* SUMMARY
- X/* maintain modification times of files
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* nfs
- X/* SYNOPSIS
- X/* #include "mtime.h"
- X/*
- X/* MTIME *mtime(path)
- X/* char *path;
- X/* DESCRIPTION
- X/* mtime() maintains a table of modification times of files.
- X/* If a new file name is given, a modification time of 0 is
- X/* assumed (the UNIX equivalent of "a very long time ago").
- X/*
- X/* If, for whatever reason, no memory can be allocated to update the
- X/* symbol table, a dummy entry is returned with modification time of 0.
- X/* DIAGNOSTICS
- X/* Diagnostics are logged with the syslog(3) facility. The program
- X/* tries to continue to run as long as possible.
- X/* BUGS
- X/* The dummy entry is stored in static memory; its value may be
- X/* overwritten an any time.
- X/* AUTHOR(S)
- X/* Wietse Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Oct 29 15:48:01 MET 1989
- X/* LAST MODIFICATION DATE
- X/* 10/29/89 22:29:56
- X/* VERSION/RELEASE
- X/* 1.1
- X/*--*/
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) mtime.c 1.1 10/29/89 22:29:56";
- X
- X#endif
- X
- X#ifdef SYSLOG
- X#include <syslog.h>
- X#else
- X#include "syslog.h"
- X#endif
- X
- X#include "mtime.h"
- X
- Xextern char *malloc();
- Xextern char *strcpy();
- X
- XMTIME *mtime_tree; /* head of symbol table */
- X
- X/* findtime - actual symbol-table access routine */
- X
- XMTIME *findtime(path, tree)
- Xregister char *path;
- Xregister MTIME *tree;
- X{
- X register int direct;
- X static MTIME dummy;
- X
- X /*
- X * We use a trivial binary-tree storage scheme. If we cannot get memory
- X * for whatever reason, produce a dummy result. This means we will always
- X * believe that a file has changed. My first excercise in "graceful
- X * degradation".
- X */
- X
- X if (tree == 0) { /* new file */
- X if ((tree = (MTIME *) malloc(sizeof(MTIME))) == 0
- X || (tree->path = malloc(strlen(path) + 1)) == 0) {
- X syslog(LOG_WARNING, "memory allocation failed");
- X dummy.time = 0;
- X tree = &dummy;
- X } else {
- X (void) strcpy(tree->path, path);
- X tree->time = 0;
- X tree->left = tree->rite = 0;
- X }
- X } else if ((direct = strcmp(path, tree->path)) < 0) {
- X tree->left = findtime(path, tree->left);
- X } else if (direct > 0) {
- X tree->rite = findtime(path, tree->rite);
- X }
- X return (tree);
- X}
- X
- END_OF_FILE
- if test 2331 -ne `wc -c <'mtime.c'`; then
- echo shar: \"'mtime.c'\" unpacked with wrong size!
- fi
- # end of 'mtime.c'
- fi
- if test -f 'mtime.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mtime.h'\"
- else
- echo shar: Extracting \"'mtime.h'\" \(943 characters\)
- sed "s/^X//" >'mtime.h' <<'END_OF_FILE'
- X/*++
- X/* NAME
- X/* mtime 5
- X/* SUMMARY
- X/* maintain modification times of files
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* nfs
- X/* SYNOPSIS
- X/* #include "mtime.h"
- X/* DESCRIPTION
- X/* .nf
- X
- X /* structure of one symbol-table entry */
- X
- Xtypedef struct MTIME {
- X char *path; /* key */
- X long time; /* value */
- X struct MTIME *left; /* left subtree */
- X struct MTIME *rite; /* right subtree */
- X} MTIME;
- X
- X /* client interface */
- X
- X#define mtime(path) (mtime_tree = findtime(path,mtime_tree))
- X
- X /* actual interface */
- X
- Xextern MTIME *mtime_tree; /* head of symbol table */
- XMTIME *findtime(); /* actual access function */
- X
- X/* AUTHOR(S)
- X/* Wietse Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Oct 29 15:48:01 MET 1989
- X/* LAST MODIFICATION DATE
- X/* 10/29/89 22:29:58
- X/* VERSION/RELEASE
- X/* 1.1
- X/*--*/
- X
- END_OF_FILE
- if test 943 -ne `wc -c <'mtime.h'`; then
- echo shar: \"'mtime.h'\" unpacked with wrong size!
- fi
- # end of 'mtime.h'
- fi
- if test -f 'dosunix.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'dosunix.c'\"
- else
- echo shar: Extracting \"'dosunix.c'\" \(2720 characters\)
- sed "s/^X//" >'dosunix.c' <<'END_OF_FILE'
- X/*++
- X/* NAME
- X/* dosunix 3
- X/* SUMMARY
- X/* UNIX <-> MS-DOS text format conversion
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* nfs
- X/* SYNOPSIS
- X/* #include <stdio.h>
- X/* #include "dosunix.h"
- X/*
- X/* int dos2unix(ifp, ofp)
- X/* FILE *ifp;
- X/* FILE *ofp;
- X/*
- X/* int unix2dos(ifp, ofp)
- X/* FILE *ifp;
- X/* FILE *ofp;
- X/*
- X/* char *dosgets(buf, len, fp)
- X/* char *buf;
- X/* unsigned len;
- X/* FILE *fp;
- X/* DESCRIPTION
- X/* dos2unix() converts an MS-DOS text stream (with cr/lf-delimited
- X/* lines) to a UNIX style stream (with lf-delimited lines).
- X/*
- X/* unix2dos() performs the opposite function as dos2unix().
- X/*
- X/* dosgets() reads one line from the designated stream and strips
- X/* off any cr of lf characters.
- X/* DIAGNOSTICS
- X/* dos2unix(), unix2dos() return a nonzero value if an error was detected.
- X/*
- X/* dosgets() returns (char *) 0 if it could not read any data.
- X/* BUGS
- X/* Very long lines will be broken; Ctrl-Z in MS-DOS files is not
- X/* given special treatment, nor will it be added to the end of
- X/* MS-DOS files.
- X/* AUTHOR(S)
- X/* Wietse Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Oct 29 16:41:50 MET 1989
- X/* LAST MODIFICATION
- X/* 10/29/89 22:30:00
- X/* VERSION/RELEASE
- X/* 1.1
- X/*--*/
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) dosunix.c 1.1 10/29/89 22:30:00";
- X
- X#endif
- X
- X#include <stdio.h>
- X#include "dosunix.h" /* consistency check */
- X
- Xextern char *strchr();
- Xextern char *fgets();
- X
- X/* unix2dos - copy UNIX-format stream to MS-DOS-format stream */
- X
- Xint unix2dos(ifp, ofp)
- XFILE *ifp;
- XFILE *ofp;
- X{
- X static char buf[BUFSIZ];
- X register int end;
- X
- X while (fgets(buf, sizeof(buf), ifp)) {
- X if (buf[end = strlen(buf) - 1] == '\n') {
- X buf[end] = '\r';
- X (void) fputs(buf, ofp);
- X (void) putc('\n', ofp);
- X } else {
- X (void) fputs(buf, ofp);
- X }
- X }
- X return (fflush(ofp) || ferror(ofp) || feof(ofp));
- X}
- X
- X/* dos2unix - copy MS-DOS-format text stream to UNIX-format text stream */
- X
- Xint dos2unix(dfp, pfp)
- Xregister FILE *dfp;
- Xregister FILE *pfp;
- X{
- X static char msgbuf[BUFSIZ]; /* copy buffer */
- X
- X while (dosgets(msgbuf, sizeof(msgbuf), dfp)) {
- X (void) fputs(msgbuf, pfp);
- X (void) putc('\n', pfp);
- X }
- X return (fflush(pfp) || ferror(pfp) || feof(pfp));
- X}
- X
- X/* dosgets - read one line from DOS-format text stream; strip cr and lf */
- X
- Xchar *dosgets(buf, len, fp)
- Xregister char *buf;
- Xunsigned len;
- Xregister FILE *fp;
- X{
- X register char *cp;
- X register char *ret;
- X
- X /* Lines with >= len characters will be broken */
- X
- X if ((ret = fgets(buf, len, fp))
- X && ((cp = strchr(buf, '\r')) || (cp = strchr(buf, '\n'))))
- X *cp = '\0'; /* strip cr or lf */
- X return (ret);
- X}
- X
- END_OF_FILE
- if test 2720 -ne `wc -c <'dosunix.c'`; then
- echo shar: \"'dosunix.c'\" unpacked with wrong size!
- fi
- # end of 'dosunix.c'
- fi
- if test -f 'dosunix.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'dosunix.h'\"
- else
- echo shar: Extracting \"'dosunix.h'\" \(779 characters\)
- sed "s/^X//" >'dosunix.h' <<'END_OF_FILE'
- X/*++
- X/* NAME
- X/* dosunix 5
- X/* SUMMARY
- X/* UNIX <-> MS-DOS text format conversion
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* nfs
- X/* SYNOPSIS
- X/* #include <stdio.h>
- X/* #include "dosunix.h"
- X/* DESCRIPTION
- X/* .nf
- X
- X /* Anticipate ANSI-compatible compilers */
- X
- X#ifdef __STDC__
- Xint unix2dos(FILE * ifp, FILE * ofp);
- Xint dos2unix(FILE * dfp, FILE * pfp);
- Xchar *dosgets(char *buf, int len, FILE * fp);
- X
- X#else
- Xint unix2dos();
- Xint dos2unix();
- Xchar *dosgets();
- X
- X#endif
- X/* AUTHOR(S)
- X/* Wietse Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Oct 29 16:41:50 MET 1989
- X/* LAST MODIFICATION
- X/* 10/29/89 22:30:05
- X/* VERSION/RELEASE
- X/* 1.1
- X/*--*/
- X
- END_OF_FILE
- if test 779 -ne `wc -c <'dosunix.h'`; then
- echo shar: \"'dosunix.h'\" unpacked with wrong size!
- fi
- # end of 'dosunix.h'
- fi
- if test -f 'percentm.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'percentm.h'\"
- else
- echo shar: Extracting \"'percentm.h'\" \(562 characters\)
- sed "s/^X//" >'percentm.h' <<'END_OF_FILE'
- X/*++
- X/* NAME
- X/* percentm 5
- X/* SUMMARY
- X/* convert %m to system error message
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* nfs
- X/* SYNOPSIS
- X/* #include percentm.h
- X/* DESCRIPTION
- X/* .nf
- X
- X /* external interface of the percentm module */
- X
- Xextern char *percentm();
- X
- X/* AUTHOR(S)
- X/* Wietse Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Oct 29 15:29:37 MET 1989
- X/* LAST MODIFICATION
- X/* 10/29/89 22:31:53
- X/* VERSION/RELEASE
- X/* 1.1
- X/*--*/
- X
- END_OF_FILE
- if test 562 -ne `wc -c <'percentm.h'`; then
- echo shar: \"'percentm.h'\" unpacked with wrong size!
- fi
- # end of 'percentm.h'
- fi
- if test -f 'percentm.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'percentm.c'\"
- else
- echo shar: Extracting \"'percentm.c'\" \(1694 characters\)
- sed "s/^X//" >'percentm.c' <<'END_OF_FILE'
- X/*++
- X/* NAME
- X/* percentm 3
- X/* SUMMARY
- X/* convert %m to system error message
- X/* PROJECT
- X/* pc-mail
- X/* PACKAGE
- X/* nfs
- X/* SYNOPSIS
- X/* #include percentm.h
- X/*
- X/* char *percentm(string, err)
- X/* char *string;
- X/* int err;
- X/* DESCRIPTION
- X/* percentm() interprets %m format specificiers in \fIstring\fR
- X/* In the output, %m will be replaced by the error message that
- X/* corresponds with the error value \fIerr\fR (see <errno.h>.
- X/* BUGS
- X/* The result is stored in static memory that is overwritten with
- X/* each call.
- X/* AUTHOR(S)
- X/* Wietse Z. Venema
- X/* Eindhoven University of Technology
- X/* Department of Mathematics and Computer Science
- X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X/* CREATION DATE
- X/* Sun Oct 29 15:29:37 MET 1989
- X/* LAST MODIFICATION
- X/* 10/29/89 22:30:06
- X/* VERSION/RELEASE
- X/* 1.1
- X/*--*/
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#) percentm.c 1.1 10/29/89 22:30:06";
- X
- X#endif
- X
- X#include <stdio.h>
- X#include "percentm.h"
- X
- Xextern int errno;
- Xextern char *sys_errlist[];
- Xextern int sys_nerr;
- Xextern char *strcpy();
- X
- X/* percentm - replace %m by error message associated with value in err */
- X
- Xchar *percentm(str, err)
- Xchar *str;
- Xint err;
- X{
- X static char buf[BUFSIZ];
- X register char *ip = str;
- X register char *op = buf;
- X
- X while (*ip) {
- X switch (*ip) {
- X case '%':
- X switch (ip[1]) {
- X case '\0': /* don't fall off end */
- X *op++ = *ip++;
- X break;
- X case 'm': /* replace %m */
- X (void) strcpy(op,
- X sys_errlist[(err < sys_nerr && err > 0) ? err : 0]);
- X op += strlen(op);
- X ip += 2;
- X break;
- X default: /* leave %<any> alone */
- X *op++ = *ip++, *op++ = *ip++;
- X break;
- X }
- X default:
- X *op++ = *ip++;
- X }
- X }
- X return (buf);
- X}
- X
- END_OF_FILE
- if test 1694 -ne `wc -c <'percentm.c'`; then
- echo shar: \"'percentm.c'\" unpacked with wrong size!
- fi
- # end of 'percentm.c'
- fi
- if test -f 'pc-mail.8' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'pc-mail.8'\"
- else
- echo shar: Extracting \"'pc-mail.8'\" \(1779 characters\)
- sed "s/^X//" >'pc-mail.8' <<'END_OF_FILE'
- X.TH PC-MAIL 8
- X.ad
- X.fi
- X.SH NAME
- Xpc-mail
- X\-
- Xdeliver mail to nfs-based pc-mail users
- X.SH PROJECT
- X.na
- X.nf
- Xpc-mail
- X.SH PACKAGE
- X.na
- X.nf
- Xnfs
- X.SH SYNOPSIS
- X.na
- X.nf
- Xpc-mail user
- X.SH DESCRIPTION
- X.ad
- X.fi
- XThis program is to be run on the nfs server that exports mail
- Xdirectories to MS-DOS pc-mail users. The program replaces the
- XUNIX -> MS-DOS file transfer function of the MS-DOS \fIcico\fR
- Xprogram.
- X
- XNormally, the pc-mail delivery program is invoked by sendmail(8).
- XIts purpose is to deliver new mail in the mail directory of the
- Xspecified \fIuser\fR (default /var/spool/pc-mail/\fIuser\fR).
- XAny error conditions detected by the pc-mail delivery program
- Xare reported back in a sendmail-compatible manner.
- X
- XThis program must be run with root privileges. It will assume
- Xthe (uid, gid) of the specified user before delivering mail.
- X
- XThe program attempts to create any missing directories, and to
- Xcorrect ownerships or protections where needed.
- X.SH FILES
- X.na
- X.nf
- X/usr/spool/pc-mail/\fIuser\fR/nNNNNN, mail message.
- X/usr/spool/pc-mail/\fIuser\fR/hNNNNN, sender of message.
- X(NNNNN is the pc-mail "message id").
- X.SH SEE ALSO
- X.na
- X.nf
- Xpc-maild(1)
- X.SH DIAGNOSTICS
- X.ad
- X.fi
- XAll conceivable error conditions cause the program to terminate
- Xwith a non-zero exit status, after printing an error message on
- Xthe standard error stream, and appending an entry to the system log.
- XSee <sysexits.h> for details.
- X.SH BUGS
- X.ad
- X.fi
- XThere is no way to notify a pc-mail user of the arrival of new mail.
- X.SH AUTHOR(S)
- X.na
- X.nf
- XW.Z. Venema
- XEindhoven University of Technology
- XDepartment of Mathematics and Computer Science
- XDen Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X.SH CREATION DATE
- X.na
- X.nf
- XSun Oct 22 18:00:53 MED 1989
- X.SH LAST MODIFICATION
- X.na
- X.nf
- X11/19/89 13:46:04
- X.SH VERSION/RELEASE
- X.na
- X.nf
- X1.2
- END_OF_FILE
- if test 1779 -ne `wc -c <'pc-mail.8'`; then
- echo shar: \"'pc-mail.8'\" unpacked with wrong size!
- fi
- # end of 'pc-mail.8'
- fi
- if test -f 'pc-maild.8' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'pc-maild.8'\"
- else
- echo shar: Extracting \"'pc-maild.8'\" \(1766 characters\)
- sed "s/^X//" >'pc-maild.8' <<'END_OF_FILE'
- X.TH PC-MAILD 8
- X.ad
- X.fi
- X.SH NAME
- Xpc-maild
- X\-
- Xdeliver unsent mail
- X.SH PROJECT
- X.na
- X.nf
- Xpc-mail
- X.SH PACKAGE
- X.na
- X.nf
- Xnfs
- X.SH SYNOPSIS
- X.na
- X.nf
- Xpc-maild [delay]
- X.SH DESCRIPTION
- X.ad
- X.fi
- XThis program should be run on the nfs file server that exports
- Xmail directories to MS-DOS pc-mail users. It replaces the
- X(MS-DOS -> UNIX) transmission function of the MS-DOS \fIcico\fR
- Xprogram.
- X
- XThe per-user mail directories (default: /var/spool/pc-mail/\fIuser\fR)
- Xare scanned for outgoing mail every \fIdelay\fR seconds (default: 300).
- XWhen outgoing mail is found, it is sent through the UNIX rmail program
- X(uucp mail interface) and the corresponding files are removed from the
- Xuser\'s mail directory.
- X
- XThe program should run with root privileges. It will assume
- Xthe (uid, gid) of the sending user before accessing mail files.
- X.SH COMMANDS
- X.na
- X.nf
- Xrmail(1), uucp mail interface program
- X.SH FILES
- X.na
- X.nf
- X/usr/spool/pc-mail/\fIuser\fR/dNNNNN, mail message
- X/usr/spool/pc-mail/\fIuser\fR/xNNNNN, recipients
- X(NNNNN is the pc-mail "message id").
- X.SH SEE ALSO
- X.na
- X.nf
- Xpc-mail(1)
- X.SH DIAGNOSTICS
- X.ad
- X.fi
- XErrors found during initialization cause the program to
- Xterminate with a diagnostic on the standard error stream.
- XAll other errors are considered transient, i.e. if something
- Xfails, it is tried again at a later time. Where possible,
- Xdiagnostics are logged through the syslog facility.
- X.SH BUGS
- X.ad
- X.fi
- XScanning mail directories is an inefficient way to detect
- Xunsent mail.
- X.SH AUTHOR(S)
- X.na
- X.nf
- XW.Z. Venema
- XEindhoven University of Technology
- XDepartment of Mathematics and Computer Science
- XDen Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- X.SH CREATION DATE
- X.na
- X.nf
- XSun Oct 22 22:12:15 MED 1989
- X.SH LAST MODIFICATION
- X.na
- X.nf
- X10/31/89 15:44:54
- X.SH VERSION/RELEASE
- X.na
- X.nf
- X1.3
- END_OF_FILE
- if test 1766 -ne `wc -c <'pc-maild.8'`; then
- echo shar: \"'pc-maild.8'\" unpacked with wrong size!
- fi
- # end of 'pc-maild.8'
- fi
- echo shar: End of shell archive.
- exit 0
-
-